using DmServer.Core.Helper;

using WindowFinder;

namespace Test;

public partial class MainForm : Form
{
    public static TcpClient? client = null;
    private int clientSizeWidth = 1000;
    private int clientSizeHeight = 600;

    public MainForm()
    {
        InitializeComponent();
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        EnsureSearchServerRunning();
        client = new TcpClient();
        //从服务器收到信息
        client.Received = (client, e) =>
        {
            string mes = CryptoHelper.DecryptDES(e.ByteBlock.ToArray());
            this.txtbox_log.Invoke(new Action(() => { WriteLog($"{mes}", Color.Green); }));

            return EasyTask.CompletedTask;
        };

        //载入配置
        client.SetupAsync(new TouchSocketConfig()
             .SetRemoteIPHost("127.0.0.1:17789")
             .SetTcpDataHandlingAdapter(() => new FixedHeaderPackageAdapter())
             .SetSendTimeout(20000)
             .ConfigurePlugins(a =>
             {
                 a.UseTcpReconnection();
             }));

        client.ConnectAsync();
    }

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        Program.CloseSearchServerIfLastInstance();
    }
    private void EnsureSearchServerRunning()
    {
        string searchServerProcessName = "DmServer";
        Process[] searchServerProcesses = Process.GetProcessesByName(searchServerProcessName);

        if (searchServerProcesses.Length == 0) // If SearchServer process is not running
        {
            // 创建一个新的进程启动信息
            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                FileName = "DmServer.exe", // 指定要启动的控制台程序
                Arguments = "", // 传递给控制台程序的参数
                UseShellExecute = false, // 是否使用操作系统外壳启动程序
                RedirectStandardOutput = false, // 是否重定向标准输出
                RedirectStandardError = false, // 是否重定向错误输出
                RedirectStandardInput = false, // 是否重定向标准输入
                CreateNoWindow = false // 是否创建没有窗口的进程
            };

            // 启动进程
            Process process = new Process
            {
                StartInfo = startInfo
            };
            process.Start();
        }
    }

    private void Finder_Window_WindowHandleChanged(object sender, EventArgs e)
    {
        var finder = (WindowFinder.WindowFinder)sender;
        Txt_WindowClassName.Text = finder.WindowClass;
        Txt_WindowHwnd.Text = finder.WindowHandle.ToString();
        Txt_WindowTitle.Text = finder.WindowText;
        Txt_WindowPID.Text = finder.WindowPID.ToString();

        IntPtr newWnd = finder.WindowHandle;
        IntPtr rootWnd = newWnd;
        do
        {
            newWnd = Win32.GetParent(newWnd);
            if (newWnd == IntPtr.Zero) break;
            rootWnd = newWnd;
        } while (true);
    }
    private void WriteLog(string info, Color color)
    {
        var timeNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        string logText = $"[{timeNow}] {info} {Environment.NewLine}";

        AppendText(logText, color);
    }
    private void AppendText(string text, Color color)
    {
        txtbox_log.SelectionStart = txtbox_log.TextLength;
        txtbox_log.SelectionLength = 0;

        txtbox_log.SelectionColor = color;
        txtbox_log.AppendText(text);
        txtbox_log.SelectionColor = txtbox_log.ForeColor;
    }

    private void btn_clear_Click(object sender, EventArgs e)
    {
        this.txtbox_log.Clear();
    }

    private async void btn_binding_Click(object sender, EventArgs e)
    {
        var pid = this.Txt_WindowPID.Text;
        var title = this.Txt_WindowTitle.Text;
        var className = this.Txt_WindowClassName.Text;

        if (string.IsNullOrWhiteSpace(pid) || string.IsNullOrWhiteSpace(title))
        {
            this.txtbox_log.Invoke(new Action(() => { WriteLog("请先选择需要绑定窗体！", Color.Red); }));
            return;
        }

        var waitingClient = client.CreateWaitingClient(new WaitingOptions());
        StringRequestInfo requestInfo = new StringRequestInfo();
        requestInfo.Method = "BindWindowEx";
        //requestInfo.Parameters = new string[] { Txt_WindowHwnd.Text, "dx.graphic.3d.10plus", "windows", "dx.keypad.input.lock.api|dx.keypad.state.api|dx.keypad.api", "", "0" };
        requestInfo.Parameters = new string[] { Txt_WindowHwnd.Text, "gdi", "normal", "normal", "", "0" };
        var message = SerializeConvert.ToJsonString(requestInfo);
        Stopwatch stopwatch = new Stopwatch();
        // 启动计时
        stopwatch.Start();
        var bytes =await waitingClient.SendThenReturnAsync(CryptoHelper.EncryptDES(message), millisecondsTimeout:20000);
        // 停止计时
        stopwatch.Stop();
        Debug.WriteLine($"代码段耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
        if (bytes == null)
        {
            this.txtbox_log.Invoke(new Action(() => { WriteLog($"窗口绑定失败！", Color.Red); }));
            return;
        }

        string mes = CryptoHelper.DecryptDES(bytes);
        if (mes == "1")
        {
            this.btn_binding.Enabled = false;
            this.txtbox_log.Invoke(new Action(() => { WriteLog($"窗口绑定成功！", Color.Green); }));
        }
        else
            this.txtbox_log.Invoke(new Action(() => { WriteLog(mes, Color.Red); }));



        requestInfo = new StringRequestInfo();
        requestInfo.Method = "GetClientSize";
        requestInfo.Parameters = new string[] { Txt_WindowHwnd.Text };

        message = SerializeConvert.ToJsonString(requestInfo);

        bytes = await waitingClient.SendThenReturnAsync(CryptoHelper.EncryptDES(message), millisecondsTimeout: 20000);
        if (bytes != null)
        {
            mes = CryptoHelper.DecryptDES(bytes);
            this.txtbox_log.Invoke(new Action(() => { WriteLog($"{mes}", Color.Green); }));

            var list = SerializeConvert.FromJsonString<List<string>>(mes);
            int.TryParse(list?[0], out int width);
            int.TryParse(list?[1], out int heigh);

            requestInfo = new StringRequestInfo();
            requestInfo.Method = "GetScreenDataBmp";
            requestInfo.Parameters = new string[] { "0", "0", width.ToString(), heigh.ToString() };

            message = SerializeConvert.ToJsonString(requestInfo);

            bytes =await waitingClient.SendThenReturnAsync(CryptoHelper.EncryptDES(message), millisecondsTimeout: 20000);
            if (bytes != null)
            {
                var picData = CryptoHelper.DecryptDESToByteArr(bytes);
                //将 byte 数组转换为 Image 对象
                using MemoryStream ms = new MemoryStream(picData);
                var image = Image.FromStream(ms);
                image.Save(DateTime.Now.ToString("yyyyMMddHHHHmmss") + "image.png");
                this.txtbox_log.Invoke(new Action(() => { WriteLog($"图片保存成功！", Color.Green); }));
            }
        }
    }
}
